package io.babystar;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;

public class NewImageUtils {
    /**
     * @param file      源文件(图片)
     * @param waterFile 水印文件(图片)
     * @param x         距离右下角的X偏移量
     * @param y         距离右下角的Y偏移量
     * @param alpha     透明度, 选择值从0.0~1.0: 完全透明~完全不透明
     * @return BufferedImage
     * @throws IOException
     * @Title: 构造图片
     * @Description: 生成水印并返回java.awt.image.BufferedImage
     */
    public static BufferedImage watermark(URL file, URL waterFile, int x, int y, int waterImgWidth, int waterImgHeight, float alpha) throws IOException {
        // 获取底图
        BufferedImage buffImgOld = ImageIO.read(file);
        // 修改尺寸
        Image tmp = buffImgOld.getScaledInstance(400,650, Image.SCALE_SMOOTH);
        // 修改尺寸
        BufferedImage buffImg = new BufferedImage(400,650, BufferedImage.TYPE_INT_ARGB);

        // 获取层图
        BufferedImage waterImg = ImageIO.read(waterFile);
        // 创建Graphics2D对象，用在底图对象上绘图
        Graphics2D g2d = buffImg.createGraphics();
        // 修改尺寸
        g2d.drawImage(tmp, 0, 0, null);


        //int waterImgWidth = waterImg.getWidth();// 获取层图的宽度
        //int waterImgHeight = waterImg.getHeight();// 获取层图的高度
        // 在图形和图像中实现混合和透明效果
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));

        g2d.drawImage(waterImg, x, y, waterImgWidth, waterImgHeight, null);
        g2d.dispose();// 释放图形上下文使用的系统资源

        return buffImg;
    }





    /**
     * 输出水印图片
     *
     * @param buffImg  图像加水印之后的BufferedImage对象
     * @param savePath 图像加水印之后的保存路径
     */
    private void generateWaterFile(BufferedImage buffImg, String savePath) {
        int temp = savePath.lastIndexOf(".") + 1;
        try {
            ImageIO.write(buffImg, savePath.substring(temp), new File(savePath));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }

    private static BufferedImage writeText(BufferedImage image, String text, int x, int y, int fontSize) throws Exception {
        //String text = "文字居中";
        //int width = 500;
        //int height = 400;
        // 创建BufferedImage对象
        //BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
        // 获取Graphics2D
        Graphics2D g2d = image.createGraphics();
        // 画图
        g2d.setBackground(new Color(255, 255, 255));
        //g2d.setPaint(new Color(0,0,0));
        g2d.setColor(Color.black);
        //g2d.clearRect(0, 0, width, height);
        Font font = new Font("黑体", Font.PLAIN, fontSize);
        g2d.setFont(font);
        // 抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 计算文字长度，计算居中的x点坐标
        //FontMetrics fm = g2d.getFontMetrics(font);
        //int textWidth = fm.stringWidth(text);
        //int widthX = (width - textWidth) / 2;
        // 表示这段文字在图片上的位置(x,y) .第一个是你设置的内容。
        g2d.drawString(text, x, y+30);
        // 释放对象
        g2d.dispose();
        return image;
    }


    /**
     * 添加文字
     * <pre>
     *     在某个固定宽度的画板上添加文字，文字超过宽度限制自动换行
     *     其余内容如果超过最大行数，...显示
     * </pre>
     * @param image   画板
     * @param font    文字字体
     * @param text    文字
     * @param width   宽度限制
     * @param marginTop  距离顶部高度
     * @param indentWidth  首行缩进距离
     * @param lineHeight 行高
     * @param maxRow  最大行数
     * @return 返回文字所占用的高度，用于后续操作画板
     */
    private static BufferedImage drawWrapString(BufferedImage image, Font font, String text, int width, int marginTop,
                                            int marginLeft, int indentWidth, double lineHeight, int maxRow) {
        Graphics2D g2d = image.createGraphics();
        String prompt = StrUtil.maxLength(text, 1000);
        FontMetrics metrics = g2d.getFontMetrics(font);
        int length = metrics.stringWidth(prompt);
        int height = metrics.getAscent() - metrics.getLeading() - metrics.getDescent();
        int row = 1;
        double top = (lineHeight - height) / 2;
        int paddingTop = marginTop;
        int firstRowWidth = width - indentWidth;
        if (length > firstRowWidth) {
            int rowLen = 0;
            int lastIndex = 0;
            for (int i = 0; i < prompt.length(); i++) {
                rowLen += metrics.charWidth(prompt.charAt(i));
                double fontMarginHeight = row == 1 ? height + top : lineHeight + top;
                int rowWidth = row == 1 ? firstRowWidth : width;
                int leftWidth = row == 1 ?  indentWidth + marginLeft : marginLeft;
                if (rowLen >= rowWidth - 15) {
                    if (row == maxRow) {
                        String lastRowTxt = i == prompt.length() - 1 ?
                                prompt.substring(lastIndex, i + 1) : prompt.substring(lastIndex, i) + "...";
                        g2d.drawString(lastRowTxt, leftWidth, paddingTop += fontMarginHeight);
                        break;
                    }
                    rowLen = 0;
                    g2d.drawString(prompt.substring(lastIndex, i + 1), leftWidth, paddingTop += fontMarginHeight);
                    row++;
                    lastIndex = i + 1;
                }
                if (i == prompt.length() - 1) {
                    g2d.drawString(prompt.substring(lastIndex), leftWidth, paddingTop += fontMarginHeight);
                }
            }
        } else {
            int leftWidth = row == 1 ?  indentWidth + marginLeft : marginLeft;
            g2d.drawString(prompt, leftWidth, paddingTop += top + height);
        }
        // 释放对象
        g2d.dispose();
        return image;
    }

    /**
     * @param args
     * @throws IOException IO异常直接抛出了
     * @author bls
     */
    public static void main(String[] args) throws Exception {


        String json = "{\n" +
                "  \"elements\": [\n" +
                "    {\n" +
                "      \"type\": \"bg\",\n" +
                "      \"imgSrc\": \"https://xtw.hisense.com/img/login.c2695ccf.png\",\n" +
                "      \"videoSrc\": \"\",\n" +
                "      \"left\": 0,\n" +
                "      \"top\": 0,\n" +
                "      \"width\": 0,\n" +
                "      \"height\": 0,\n" +
                "      \"lineHeight\": 0,\n" +
                "      \"animatedName\": \"\",\n" +
                "      \"duration\": 1,\n" +
                "      \"delay\": 0,\n" +
                "      \"playing\": false,\n" +
                "      \"loop\": false,\n" +
                "      \"opacity\": 100,\n" +
                "      \"transform\": 0,\n" +
                "      \"text\": \"\",\n" +
                "      \"textAlign\": \"left\",\n" +
                "      \"iconKey\": \"\",\n" +
                "      \"bg\": \"\",\n" +
                "      \"fontSize\": 18,\n" +
                "      \"fontFamily\": \"微软雅黑\",\n" +
                "      \"fontWeight\": \"normal\",\n" +
                "      \"color\": \"#000000\",\n" +
                "      \"zindex\": 1\n" +
                "    },\n" +
                "    {\n" +
                "      \"type\": \"pic\",\n" +
                "      \"imgSrc\": \"https://xtw.hisense.com/img/logo.9411f887.png\",\n" +
                "      \"videoSrc\": \"\",\n" +
                "      \"left\": 84,\n" +
                "      \"top\": 348,\n" +
                "      \"width\": 156,\n" +
                "      \"height\": 136,\n" +
                "      \"lineHeight\": 0,\n" +
                "      \"animatedName\": \"\",\n" +
                "      \"duration\": 1,\n" +
                "      \"delay\": 0,\n" +
                "      \"playing\": false,\n" +
                "      \"loop\": false,\n" +
                "      \"opacity\": 100,\n" +
                "      \"transform\": 0,\n" +
                "      \"text\": \"\",\n" +
                "      \"textAlign\": \"left\",\n" +
                "      \"iconKey\": \"\",\n" +
                "      \"bg\": \"\",\n" +
                "      \"fontSize\": 18,\n" +
                "      \"fontFamily\": \"微软雅黑\",\n" +
                "      \"fontWeight\": \"normal\",\n" +
                "      \"color\": \"#000000\",\n" +
                "      \"zindex\": 3\n" +
                "    },\n" +
                "    {\n" +
                "      \"type\": \"text\",\n" +
                "      \"imgSrc\": \"\",\n" +
                "      \"videoSrc\": \"\",\n" +
                "      \"left\": 50,\n" +
                "      \"top\": 0,\n" +
                "      \"width\": 320,\n" +
                "      \"height\": 0,\n" +
                "      \"lineHeight\": 1,\n" +
                "      \"animatedName\": \"\",\n" +
                "      \"duration\": 1,\n" +
                "      \"delay\": 0,\n" +
                "      \"playing\": false,\n" +
                "      \"loop\": false,\n" +
                "      \"opacity\": 100,\n" +
                "      \"transform\": 0,\n" +
                "      \"text\": \"地址：山东省青岛市崂山区左岸风度小区29号楼2单元402\",\n" +
                "      \"textAlign\": \"left\",\n" +
                "      \"iconKey\": \"\",\n" +
                "      \"bg\": \"\",\n" +
                "      \"fontSize\": 18,\n" +
                "      \"fontFamily\": \"微软雅黑\",\n" +
                "      \"fontWeight\": \"normal\",\n" +
                "      \"color\": \"#000000\",\n" +
                "      \"zindex\": 4\n" +
                "    }\n" +

                "  ]\n" +
                "}";

        String sourceFilePath = "";
        String saveFilePath = "/Users/wanghucheng/Downloads/zhuangxiu/123.png";

        JSONObject obj = JSONObject.parseObject(json);
        JSONArray array = obj.getJSONArray("elements");

        // 生成背景
        for(int i=0;i<array.size(); i++){
            JSONObject jt = (JSONObject) array.get(i);
            String type = jt.getString("type");
            System.out.println(type);
            if("bg".equals(type)){
                sourceFilePath = jt.getString("imgSrc");
                break;
            }
        }

        // 叠加图片
        BufferedImage buffImg = null;
        for(int i=0;i<array.size(); i++){
            JSONObject jt = (JSONObject) array.get(i);
            String type = jt.getString("type");
            System.out.println(type);
            if("pic".equals(type)) {
                int x = jt.getInteger("left");
                int y = jt.getInteger("top");
                int w = jt.getInteger("width");
                int h = jt.getInteger("height");
                buffImg = NewImageUtils.watermark(new URL(sourceFilePath), new URL(jt.getString("imgSrc")), x, y, w, h, 1.0f);
                continue;
            }
        }

        // 叠加文字
        for(int i=0;i<array.size(); i++) {
            JSONObject jt = (JSONObject) array.get(i);
            String type = jt.getString("type");
            System.out.println(type);
            if ("text".equals(type)) {
                String text = jt.getString("text");
                int x = jt.getInteger("left");
                int y = jt.getInteger("top");
                int fontSize = jt.getInteger("fontSize");
                double lineHeight = jt.getDouble("lineHeight");
                int w = jt.getInteger("width");
                /**
                 *   * @param image   画板
                 *      * @param font    文字字体
                 *      * @param text    文字
                 *      * @param width   宽度限制
                 *      * @param marginTop  距离顶部高度
                 *      * @param indentWidth  首行缩进距离
                 *      * @param lineHeight 行高
                 *      * @param maxRow  最大行数
                 *
                 *      * @return 返回文字所占用的高度，用于后续操作画板
                 */
                Font font = new Font("宋体", Font.PLAIN, fontSize);
                buffImg = NewImageUtils.drawWrapString(buffImg, font, text, w, y, x, 0, fontSize*lineHeight, 3);
                continue;
            }
        }

        NewImageUtils newImageUtils = new NewImageUtils();
        // 输出图片
        newImageUtils.generateWaterFile(buffImg, saveFilePath);
    }

}
